package com.fingard.dsp.bank.directbank.gdrc01;

import java.text.DecimalFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.fingard.constant.Format;
import com.fingard.dsp.bank.directbank.DirectBase;
import com.fingard.dsp.bank.reqrespobj.single.ReqSingle;
import com.fingard.net.ITcpClient;
import com.fingard.net.TcpReceiver;
import com.fingard.net.WebRequest;
import com.fingard.xml.XElement;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;

/**
 * Created by F on 2018/10/10.
 * 公共方法
 */
public class GDRC01Base extends DirectBase implements ITcpClient {
    private static final String STR_FORMAT = "00000000";
    DecimalFormat decimalFormat = new DecimalFormat(STR_FORMAT);

    @Override
    public void getContentLength(TcpReceiver p_receiver) throws Exception {
        if (p_receiver.contentLength == -1) {
            String tmpCharset = getCharset();
            String tmpRecNow = new String(p_receiver.recBytes, 0, p_receiver.readedLength, tmpCharset);
            if (tmpRecNow.contains("<Message>")) {
                p_receiver.contentLength = p_receiver.readedLength;
                p_receiver.contentStartIndex = 0;
            }
        }
    }

    /**
     * 编码
     * @return
     */
    protected String getCharset(){
        return getBankConfig().getCharset("GB2312");
    }

    /**
     *  请求报文头
     * @param xmlWriter
     * @param p_bankHeader
     * @throws Exception
     */
    protected void writeCommonHeader(XmlTextWriter xmlWriter, GDRC01Header p_bankHeader) throws Exception{
        xmlWriter.writeStartDocByDeclaration("<?xml version=\"1.0\" encoding=\""+getCharset()+"\" ?>");
        xmlWriter.writeStartElement("Message");
        xmlWriter.writeStartElement("Head");
        xmlWriter.writeElementString("TrsCode", p_bankHeader.TrsCode);
        xmlWriter.writeElementString("ERPTrsTimestamp", addDate()+Format.DateTime14Format.format(new Date()).substring(8));
        xmlWriter.writeElementString("ERPJnlNo", p_bankHeader.ERPJnlNo);
    }

    /**
     * 发送报文至银行
     * @param p_reqStr 请求报文
     * @return
     * @throws Exception
     */
    protected String[] sendToBank(String p_reqStr) throws Exception {
        String[] retStr = new String[]{"", ""};

        WriteBankLogLn("1.提交银行的地址：" + bankFront.serverURL);
        int n = p_reqStr.getBytes("UTF-8").length;
        //String p_head = decimalFormat.format(n);
        String p_string = p_reqStr;
        WriteBankLogStep2(p_string);
        WebRequest tmpWebRequest = new WebRequest(bankFront.serverURL);
        tmpWebRequest.setConnectTimeout(60000);
        tmpWebRequest.setRequestProperty("Content-Type", "application/json");
        tmpWebRequest.setRequestProperty("connection", "Close");
        byte[] tmpToWriteBytes = p_string.getBytes(getCharset());
        retStr = tmpWebRequest.upload(tmpToWriteBytes, getCharset());
        WriteBankLogStep3(retStr[1]);
        return retStr;
    }

    /**
     * 发送报文至银行
     * @param p_reqStr 请求报文
     * @param p_code   url映射名称
     * @return
     * @throws Exception
     */
    protected String[] sendToBankForCode(String p_reqStr,String p_code) throws Exception {
        String[] retStr = new String[]{"", ""};
        String url = bankFront.getUrl(p_code);
        WriteBankLogLn("1.提交银行的地址：" + url);
        String p_string = p_reqStr;
        WriteBankLogStep2(p_string);
        WebRequest tmpWebRequest = new WebRequest(url);
        tmpWebRequest.setConnectTimeout(60000);
        tmpWebRequest.setRequestProperty("Content-Type", "application/json");
        tmpWebRequest.setRequestProperty("connection", "Close");
        String charsetName = getCharset();
        byte[] tmpToWriteBytes = p_string.getBytes(charsetName);
        retStr = tmpWebRequest.upload(tmpToWriteBytes, charsetName);
        WriteBankLogStep3(retStr[1]);
        return retStr;
    }

    protected String[] sendToBankForUploadFile(String p_reqStr,String p_code,String content) throws Exception {
        String[] retStr = new String[]{"", ""};
        String url = bankFront.getUrl(p_code) + p_reqStr;
        String dest = "";
        if (url!=null) {
            Pattern p = Pattern.compile("\\s*|\t|\r|\n");
            Matcher m = p.matcher(url);
            dest = m.replaceAll("");
        }
        WriteBankLogLn("1.提交银行的地址：" + url);
        WebRequest tmpWebRequest = new WebRequest(dest);
        tmpWebRequest.setConnectTimeout(60000);
        tmpWebRequest.setRequestProperty("Content-Type", "application/json");
        tmpWebRequest.setRequestProperty("connection", "Close");
        String charsetName = "UTF-8";
        byte[] tmpToWriteBytes = content.getBytes(charsetName);
        retStr = tmpWebRequest.upload(tmpToWriteBytes, charsetName);
        WriteBankLogStep3(retStr[1]);
        return retStr;
    }

    protected String getCustNo(ReqSingle p_req1908) throws Exception{
        String custNo="";
        //拼接请求报文头
        XmlTextWriter xmlTextWriter = new XmlTextWriter();
        GDRC01Header gdrc01Header=new GDRC01Header();
        gdrc01Header.TrsCode="B2EGroupActRelaQry";//交易码
        gdrc01Header.ERPJnlNo=p_req1908.singleDetail.askNumber;//财务系统交易流水号
        writeCommonHeader(xmlTextWriter,gdrc01Header);
        xmlTextWriter.writeEndElement();
        XElement body = new XElement("Body","");
        body.addChild(new XElement("GroupIdNo",""));//
        body.addChild(new XElement("GrouIdType",""));//
        body.addChild(new XElement("IdNo",bankFront.org));//客户组织机构代码证件号
        body.addChild(new XElement("IdType",bankFront.corpNo));//客户证件类型
        body.addChild(new XElement("AcNo",""));//账号
        body.addChild(new XElement("QryType","0"));//查询类型
        body.addChild(new XElement("State","0"));//账户状态
        body.addChild(new XElement("QryFlag","1"));//查询标识
        body.addChild(new XElement("QryHostFlag","1"));//是否查询核心余额
        xmlTextWriter.writeXElement(body);
        xmlTextWriter.writeEndDocument();

        //发送请求报文
        String[] bankResult = sendToBank(xmlTextWriter.toXmlString());

        //测试
        //bankResult[0]="";
        //bankResult[1]="<Message>   <Head>      <IBSReturnCode>000000</IBSReturnCode>      <IBSReturnMsg/>   </Head>   <Body>      <List>         <Map>            <AcNo>80020000000807809</AcNo>            <CustNo>1000003258</CustNo>            <AcName>汇海测试账号789456123</AcName>            <AcAlias>汇海主账户</AcAlias>            <Currency>CNY</Currency>            <DeptId>08351</DeptId>            <Type>0</Type>            <BusiPrivil>00</BusiPrivil>            <SignType>1</SignType>            <State>0</State>            <SignDeptId>08351</SignDeptId>            <SignOperateId>0065646</SignOperateId>            <SignTime>20251121101218</SignTime>            <UpdateDeptId>00101</UpdateDeptId>            <UpdateOperateId>7001763</UpdateOperateId>            <UpdateTime>20171129160403</UpdateTime>            <Region/>            <SuperiorAcNo/>            <GroupCustNo>1000003258</GroupCustNo>            <Level>1</Level>            <TransferMode/>            <EndDate/>            <PostionAmount>0.00</PostionAmount>            <OverdrawAmount>0.00</OverdrawAmount>            <ClaimLimitPerDay>0.00</ClaimLimitPerDay>            <HostBalance>102160.64</HostBalance>            <ClaimLimit>0.00</ClaimLimit>         </Map>      </List>   </Body></Message>\n";
        //WriteBankLogLn(bankResult[1]);

        //处理响应报文
        if (bankResult[0].length() == 0) {
            StringBuilder tmpSb = new StringBuilder();
            XmlTextReader tmpBkReader = loadBankRespXmlReader(bankResult[1], tmpSb);
            if (tmpBkReader != null) {
                String respCode = tmpBkReader.getFirstText("/Message/Head/IBSReturnCode");
                if("000000".equals(respCode)){//交易成功
                    if (tmpBkReader.read("/Message/Body/List/Map")) {
                        custNo=tmpBkReader.readedXElement.getSingleTextNotNull("CustNo");
                        WriteBankLogLn("获取客户号成功："+custNo);
                    }
                }
            }
        }
        if("".equals(custNo)){
            WriteBankLogLn("获取客户号失败");
            throw new Exception("获取客户号失败");
        }
        return custNo;
    }

    /**
     * 系统测试时间比北京时间大
     * @return
     */
    public String addDate() {
        Calendar tmpCalendarFrom = Calendar.getInstance();
        //tmpCalendarFrom.add(Calendar.DATE, 156+365*13);
        String dateFrom = Format.Date8Format.format(tmpCalendarFrom.getTime());
        return dateFrom;
    }
}
